/*
 * Copyright (c) 2024 endless-sky
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef HAL_NET_INCLUDE_HAL_NETWORK_H
#define HAL_NET_INCLUDE_HAL_NETWORK_H

#include <string>
#include <vector>
#include <mutex>
#include <functional>
#include <thread>
#include <nlohmann/json.hpp>
#include "utils_noncopyable.h"
#include "common_config_manager.h"

namespace El {
namespace Network {

// 兼容性枚举和结构体（为第三方库提供）
enum class NetIfStatus {
    UP,
    DOWN
};

struct NetIfInfo {
    std::string name;
    std::string ipv4Address;
    std::string ipv4Mask;
    std::string gateway;
    std::string macAddress;
    NetIfStatus status;
    bool hasIpv4;
    
    NetIfInfo() : status(NetIfStatus::DOWN), hasIpv4(false) {}
};

class Network : public NoCopyable {
public:
    static Network& GetInstance();
    
    // 初始化网络模块（系统启动时调用）
    bool Start();
    
    // 销毁网络模块
    void Destroy();
    
    // 配置管理
    bool LoadConfig();
    bool SaveConfig();
    
    // 生成interfaces文件（启动时和配置变更时调用）
    bool GenerateInterfacesFile();
    
    // 网络配置接口
    bool ConfigureNetworkDhcp(const std::string& interface);
    bool ConfigureNetworkStatic(const std::string& interface, 
                               const std::string& address,
                               const std::string& netmask, 
                               const std::string& gateway);
    bool ConfigureDnsServers(const std::string& dns1, const std::string& dns2 = "");
    bool SetHostname(const std::string& hostname);
    
    // 接口控制
    bool RestartInterface(const std::string& interface);
    bool GetInterfaceStatus(const std::string& interface, nlohmann::json& status);
    
    // 获取接口IP地址（为了兼容旧代码）
    std::string GetInterfaceIpAddress(const std::string& interface) const;

    // 获取接口MAC地址
    std::string GetInterfaceMacAddress(const std::string& interface) const;

    // 兼容性方法（为ONVIF等模块和第三方库提供）
    std::string GetDefaultInterfaceName() const;
    std::vector<std::string> GetDnsServers() const;
    NetIfInfo GetNetworkInterface(const std::string& interface) const;
    
    // 获取当前网络配置
    nlohmann::json GetNetworkConfig() const;
    
    // 设置网络配置
    bool SetNetworkConfig(const nlohmann::json& config);

private:
    Network();
    ~Network() = default;
    
    // 配置变更回调
    void OnConfigChanged(const std::string& path, const nlohmann::json& config);
    
    // 异步处理配置变更（避免死锁）
    void ProcessConfigChangeAsync(const std::string& path, const nlohmann::json& config);
    
    // 内部工具方法
    bool WriteInterfacesFile(const std::string& content);
    bool ApplyDnsConfig();
    bool ApplyHostname();
    bool ExecuteCommand(const std::string& command);
    std::string GetInterfacesFileContent() const;
    
    // 验证配置
    bool ValidateNetworkConfig(const nlohmann::json& config) const;
    bool ValidateInterfaceConfig(const std::string& interface, const nlohmann::json& config) const;

    // IP地址验证函数
    bool IsValidIpAddress(const std::string& ip) const;
    bool IsValidNetmask(const std::string& netmask) const;
    bool IsValidGateway(const std::string& gateway) const;
    
    // 成员变量
    mutable std::mutex mutex_;
    nlohmann::json config_;
    bool initialized_;
    int32_t config_apply_listener_id_;
    int32_t config_verify_listener_id_;
    
    // 配置路径
    static constexpr const char* INTERFACES_FILE_PATH = "/mnt/config/interfaces";
    static constexpr const char* RESOLV_CONF_PATH = "/etc/resolv.conf";
    static constexpr const char* HOSTNAME_FILE_PATH = "/etc/hostname";
    static constexpr const char* HOSTS_FILE_PATH = "/etc/hosts";
    static constexpr const char* CONFIG_PATH = "/network";
};

} // namespace Network
} // namespace El

#endif // HAL_NET_INCLUDE_HAL_NETWORK_H